<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <meta name="generator" content="HTML Tidy for Linux/x86 (vers 1st November 2003), see www.w3.org"/>
    <title>JavaScript: not-Inheritance</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta name="copyright" content="Copyright &#169; 2005-2010 W3C (MIT, ERCIM, Keio)"/>
    <meta name="duration" content="5"/>
    <meta name="font-size-adjustment" content="-2"/>

    <link rel="stylesheet" href="styles/slidy.css" type="text/css"/>
    <link rel="stylesheet" href="styles/w3c-blue.css" type="text/css"/>
    <script type="text/javascript" src="scripts/slidy.js" charset="utf-8">//</script>

    <link type="text/css" rel="stylesheet" href="styles/shCoreDefault.css"/>
    <script type="text/javascript" src="scripts/shCore.js"></script>
    <script type="text/javascript" src="scripts/shBrushJScript.js"></script>
    <script type="text/javascript" src="scripts/shBrushJava.js"></script>

    <link type="text/css" rel="stylesheet" href="styles/presentation.css"/>
    <script type="text/javascript" src="scripts/presentation.js"></script>
</head>


<body style="">
<div class="background">
    <img alt="" id="head-icon" src="graphics/icon-blue.png"/>
</div>

<div class="background slanty">
</div>

<div class="slide cover title">
    <img class="hidden" src="graphics/bullet.png" alt=""/>
    <img class="hidden" src="graphics/fold.gif" alt=""/>
    <img class="hidden" src="graphics/unfold.gif" alt=""/>
    <img class="hidden" src="graphics/fold-dim.gif" alt=""/>
    <img class="hidden" src="graphics/nofold-dim.gif" alt=""/>
    <img class="hidden" src="graphics/unfold-dim.gif" alt=""/>
    <img class="hidden" src="graphics/bullet-fold.gif" alt=""/>
    <img class="hidden" src="graphics/bullet-unfold.gif" alt=""/>
    <img class="hidden" src="graphics/bullet-fold-dim.gif" alt=""/>
    <img class="hidden" src="graphics/bullet-nofold-dim.gif" alt=""/>
    <img class="hidden" src="graphics/bullet-unfold-dim.gif" alt=""/>

    <h1>JavaScript: not-Inheritance</h1>

    <div style="position: absolute; bottom: 20px;">
        <p>Alex.Kolonitsky@gmail.com</p>

        <p>
            <a href="http://javascript-learning-courses.googlecode.com">http://javascript-learning-courses.googlecode.com</a>
        </p>
    </div>
</div>

<div class="slide">
    <h1>Content</h1>

    <ul>
        <li>Конструктор</li>
        <li>Делегирующее наследование</li>
        <li>Делегирующее наследование в JS</li>
        <li>Prototype & Constructor</li>
        <li>Classic Inheritance в JS</li>
        <li>Extend Function</li>
        <li>Other inheritance models</li>
        <li>Inheritance problems</li>
    </ul>
</div>

<div class="slide">
    <h1>Content</h1>

    <ul class="content">
        <li class="current">Конструктор</li>
        <li>Делегирующее наследование</li>
        <li>Делегирующее наследование в JS</li>
        <li>Prototype & Constructor</li>
        <li>Classic Inheritance в JS</li>
        <li>Extend Function</li>
        <li>Other inheritance models</li>
        <li>Inheritance problems</li>
    </ul>
</div>

<div class="slide">
    <h1>Cоздание Объекта: JS</h1>

    <pre class="brush: js">
        function Person(name) {
          this.name = name || "&lt;noname>";
        }

        var me = new Person("Alex");
        alert(me.name); // "Alex"
    </pre>
</div>

<div class="slide">
    <h1>Cоздание Объекта: Java</h1>

    <pre class="brush: java">
        class Person {}
            String name;
            Person(String name) {
              this.name = name;
            }
        }

        Person me = new Person("Alex");
        System.out.println(me.name); // "Alex"
    </pre>
</div>

<div class="slide">
    <h1>Cоздание Объекта</h1>

    <table style="font-size: 65%">
        <tr>
            <td>
                <pre class="brush: java, highlight: [3,4,5]">
                    class Person {}
                        String name;
                        Person(String name) {
                          this.name = name;
                        }
                    }

                    Person me = new Person("Alex");
                    System.out.println(me.name); // "Alex"
                </pre>
            </td>
            <td style="padding-top: 2.21em;">
                <pre class="brush: js, highlight: [1,2,3]">
                    function Person(name) {
                      this.name = name || "&lt;noname>";
                    }


                    var me = new Person("Alex");
                    alert(me.name); // "Alex"
                </pre>
            </td>
        </tr>
    </table>
</div>

<div class="slide">
    <h1>Алгоритм создания объекта.</h1>


    <pre class="brush: js">
        // Псевдокод на JS
        O = new NativeObject();
        //O.[[Prototype]] = F.prototype

        return F.apply(O, initialParameters) || O;
    </pre>
</div>

<div class="slide">
    <h1>Content</h1>

    <ul class="content">
        <li class="done">Конструктор</li>
        <li class="current">Делегирующее наследование</li>
        <li>Делегирующее наследование в JS</li>
        <li>Prototype & Constructor</li>
        <li>Classic Inheritance в JS</li>
        <li>Extend Function</li>
        <li>Other inheritance models</li>
        <li>Inheritance problems</li>
    </ul>
</div>

<div class="slide">
    <h1>Делегирующее наследование</h1>

    <p>Идея в том что у каждого объекта есть ссылка на прототип, и если он не может обработать сообщение он передает(делегирует) его прототипу.</p>
</div>

<div class="slide">
    <h1>Классовая модель</h1>

    <pre class="brush: java">
        class A {
            void a() {}
        }
        class B extends A {}
        class C extends B {}

        C c = new C();
        c.a()
    </pre>

    <img class="incremental" src="graphics/Inheritance/inh-theory-01.png" alt="" style="position: absolute; top: 9em; right: 0; width: 70%;">
</div>

<div class="slide">
    <h1>Делегирующая модель</h1>

    <p>Если бы мы могли управлять ссылками class и extends получилась бы такая картина:</p>

    <img src="graphics/Inheritance/inh-theory-02.png" alt="" >
</div>

<div class="slide">
    <h1>Делегирующая модель</h1>

    <p>Нет принципиальной разницы:</p>

    <img src="graphics/Inheritance/inh-theory-01.png" alt="" style="height: 150px">
    <img src="graphics/Inheritance/inh-theory-02.png" alt="" style="height: 100px">
</div>



<div class="slide">
    <h1>Ключевые моменты классовой модели</h1>

    <ul>
        <li>чтобы породить объект, нужно перед этим обязательно описать его класс</li>
        <li>разрешение методов осуществляется в жёсткой цепи наследования</li>
        <li>будучи порождённым, класс не может изменить набор характеристик</li>
    </ul>
</div>

<div class="slide">
    <h1>Ключевые особенности прототипной модели</h1>

    <ul>
        <li>основным понятием является объект</li>
        <li>у объектов нет жёстких классов, задающих их структуру и поведение</li>
        <li>в делегирующей прототипной модели, изменение характеристик прототипа отображается на всех объектах, связанных с этим прототипом</li>
    </ul>
</div>

<div class="slide">
    <h1>Prototype Pattern</h1>

    <p>Задаёт виды создаваемых объектов с помощью экземпляра-прототипа и создаёт новые объекты путём копирования этого прототипа.</p>
</div>

<div class="slide">
    <h1>Content</h1>

    <ul class="content">
        <li class="done">Конструктор</li>
        <li class="done">Делегирующее наследование</li>
        <li class="current">Делегирующее наследование в JS</li>
        <li>Prototype & Constructor</li>
        <li>Classic Inheritance в JS</li>
        <li>Extend Function</li>
        <li>Other inheritance models</li>
        <li>Inheritance problems</li>
    </ul>
</div>


<div class="slide">
    <h1>Пример создание Объекта</h1>

    <pre class="brush: js">
        function Person(name) {
          this.name = name || "&lt;noname>";
        }

        var me = new Person("Alex");
        alert(me.name); // "Alex"
    </pre>
</div>

<div class="slide">
    <h1>Алгоритм создания объекта.</h1>

    <pre class="brush: js">
        O = new NativeObject();
        O.[[Prototype]] = F.prototype

        return F.apply(O, initialParameters) || O;
    </pre>
</div>

<div class="slide">
    <h1>Алгоритм поиска свойств</h1>

    <ol>
        <li>Ищем непосредственно в объекте (O)</li>
        <li>Ищем в прототипе объекта (O.[[Prototype]])</li>
    </ol>

    <p class="incremental" style="margin-left: 3em;">Здесь появляется рекурсия.</p>
</div>

<div class="slide">
    <h1>Пример создание Объекта</h1>

    <pre class="brush: js">
        function Person(name) {
          this.name = name || "&lt;noname>";
        }

        var person = new Person; // или new Person();
        alert(person.name); // &lt;noname>

        var me = new Person("Alex");
        alert(me.name); // "Alex"
    </pre>
</div>

<div class="slide">
    <h1>Пример создание Объекта</h1>

    <img src="graphics/Inheritance/02.png" alt="">
</div>

<div class="slide">
    <h1>Content</h1>

    <ul class="content">
        <li class="done">Конструктор</li>
        <li class="done">Делегирующее наследование</li>
        <li class="done">Делегирующее наследование в JS</li>
        <li class="current">Prototype & Constructor</li>
        <li>Classic Inheritance в JS</li>
        <li>Extend Function</li>
        <li>Other inheritance models</li>
        <li>Inheritance problems</li>
    </ul>
</div>

<div class="slide">
    <h1>Функции: API</h1>

    <dl>
        <dt>Properties</dt>
        <dd><strong>prototype</strong>, caller, constructor, length, name</dd>
        <dt>Methods</dt>
        <dd>apply, call, toString</dd>
    </dl>
</div>

<div class="slide">
    <h1>&lt;function>.prototype</h1>

    <pre class="brush: js">
        function A() {}
    </pre>


    <pre class="brush: js">
        // это псевдокод

        var A = {
            prototype: {
                constructor: A
            }
        }
    </pre>

    <img src="graphics/Inheritance/01.png" alt="" style="position: absolute; top: 5em; right: 0; width: 60%;">
</div>


<div class="slide">
    <h1>constructor</h1>

    <p>Cвойство constructor записывается в свойство функции prototype при создании; значением данного свойства является ссылка на саму функцию</p>

    <pre class="brush: js">
        function A() {}
        console.log(A.prototype.constructor === A);
    </pre>
</div>

<div class="slide">
    <h1>&lt;function>.prototype</h1>

    <p>Это такой же объект как все остальные.</p>

    <pre class="brush: js">
        function A() {}
        A.prototype.x = 10;
        A.prototype.y = 20;
        console.dir(A.prototype)

        delete A.prototype.x
        console.dir(A.prototype)

        A.prototype = {"one": 1, "two": 2}
    </pre>
</div>

<div class="slide">
    <h1>Пример</h1>

    <pre class="brush: js">
        function A() {}
        A.prototype = {
          x: 10
        };

        var a = new A();
        alert(a.x); // 10
        alert(a.constructor === A); // false!
    </pre>

    <img class="incremental" src="graphics/Inheritance/03.png" alt="" style="position: absolute; top: 3em; right: 0.5em; width: 60%">
</div>

<div class="slide">
    <h1>Пример</h1>

    <pre class="brush: js, highlight: 3">
        function A() {}
        A.prototype = {
          constructor: A,
          x: 10
        };

        var a = new A();
        alert(a.x); // 10
        alert(a.constructor === A); // true
    </pre>

    <img class="incremental" src="graphics/Inheritance/04.png" alt="" style="position: absolute; top: 3em; right: 0; width: 60%">
</div>

<div class="slide">
    <h1>Общие методы</h1>

    <pre class="brush: js">
        function A() {
            this.y = 20
        }
        A.prototype.x = 10;

        var a = new A();
        a.z = 30;
        console.dir(a)
    </pre>

    <img class="incremental" src="graphics/Inheritance/05.png" alt="" style="position: absolute; top: 2em; right: 0; width: 65%">
</div>

<div class="slide">
    <h1>Можно заменить прототип</h1>

    <pre class="brush: js">
        function A() {}
        A.prototype.x = 10;

        var a = new A();
        console.dir(a); // {x: 10}

        A.prototype = {x: 20, y: 30};

        var b = new A();
        console.dir(a); // {x: 10}
        console.dir(b); // {x: 20, y: 30}
    </pre>
</div>

<div class="slide">
    <h1>Можно заменить прототип</h1>

    <pre class="brush: js, highlight: [1,2,3,4,5]">
        function A() {}
        A.prototype.x = 10;

        var a = new A();
        console.dir(a); // {x: 10}

        A.prototype = {x: 20, y: 30};

        var b = new A();
        console.dir(a); // {x: 10}
        console.dir(b); // {x: 20, y: 30}
    </pre>

    <img class="incremental" src="graphics/Inheritance/04.png" alt="" style="position: absolute; top: 2em; right: 0; width: 60%">
</div>

<div class="slide">
    <h1>Можно заменить прототип</h1>

    <pre class="brush: js, highlight: [7,8,9,10,11]">
        function A() {}
        A.prototype.x = 10;

        var a = new A();
        console.dir(a); // {x: 10}

        A.prototype = {x: 20, y: 30};

        var b = new A();
        console.dir(a); // {x: 10}
        console.dir(b); // {x: 20, y: 30}
    </pre>

    <img src="graphics/Inheritance/04.png" alt="" style="position: absolute; top: 2em; right: 0; width: 60%">
</div>

<div class="slide">
    <h1>Можно заменить прототип 01</h1>

    <img src="graphics/Inheritance/06.png" alt="" style="width:90%">
</div>

<div class="slide">
    <h1>Можно заменить прототип</h1>

    <pre class="brush: js, highlight: [8]">
        function A() {}
        A.prototype.x = 10;
        var a = new A();

        A.prototype = {x: 20, y: 30};

        var b = new A();
        var c = new A();
        console.dir(a, b, c); // {x: 10} {x: 20, y: 30}  {x: 20, y: 30}
    </pre>
</div>

<div class="slide">
    <h1>Можно заменить прототип</h1>

    <img src="graphics/Inheritance/07.png" alt="" style="width:90%">
</div>

<div class="slide">
    <h1>Можно заменить прототип</h1>

    <pre class="brush: js, highlight: [10]">
        function A() {}
        A.prototype.x = 10;
        var a = new A();

        A.prototype = {x: 20, y: 30};

        var b = new A();
        var c = new A();

        b.x = "Hello";
    </pre>
</div>


<div class="slide">
    <h1>Можно заменить прототип</h1>

    <img src="graphics/Inheritance/08.png" alt="" style="width:100%">
</div>

<div class="slide">
    <h1>Можно заменить прототип</h1>

    <pre class="brush: js, highlight: [11]">
        function A() {}
        A.prototype.x = 10;
        var a = new A();

        A.prototype = {x: 20, y: 30};

        var b = new A();
        var c = new A();

        b.x = "Hello";
        A.prototype.x = "new x";
        console.log(a.x, b.x, c.x);
    </pre>
</div>


<div class="slide">
    <h1>Можно заменить прототип</h1>

    <img src="graphics/Inheritance/09.png" alt="" style="width:100%">
</div>

<div class="slide">
    <h1>Как испортить свой конструктор</h1>

    <pre class="brush: js">
        function A(name) {
            this.name = name;

            return {foo: 5};
        }

        console.log(new A());
    </pre>
</div>

<div class="slide">
    <h1>Content</h1>

    <ul class="content">
        <li class="done">Конструктор</li>
        <li class="done">Делегирующее наследование</li>
        <li class="done">Делегирующее наследование в JS</li>
        <li class="done">Prototype & Constructor</li>
        <li class="current">Classic Inheritance</li>
        <li>Extend Function</li>
        <li>Other inheritance models</li>
        <li>Inheritance problems</li>
    </ul>
</div>

<div class="slide">
    <h1>Classic Inheritance</h1>

    <pre class="brush: js">
        function Parent() {}
        function Child() {}

        Child.prototype = new Parent();
        Child.prototype.constructor = Child;
    </pre>

    <p class="incremental">Рассмотрим по шагам что здесь происходит.</p>
</div>

<div class="slide">
    <h1>Classic Inheritance</h1>

    <pre class="brush: js, highlight: [1,2]">
        function Parent() {}
        function Child() {}





        Child.prototype = new Parent();
        Child.prototype.constructor = Child;
    </pre>

    <img class="incremental" src="graphics/Inheritance/classic_01.png" alt="" style="position: absolute; top: 2em; right: 0; width: 50%">
</div>

<div class="slide">
    <h1>Classic Inheritance</h1>

    <pre class="brush: js, highlight: [8]">
        function Parent() {}
        function Child() {}





        Child.prototype = new Parent();
        Child.prototype.constructor = Child;
    </pre>

    <img src="graphics/Inheritance/classic_01.png" alt="" style="position: absolute; top: 2em; right: 0; width: 50%">
</div>

<div class="slide">
    <h1>Classic Inheritance</h1>

    <pre class="brush: js, highlight: [8]">
        function Parent() {}
        function Child() {}





        Child.prototype = new Parent();
        Child.prototype.constructor = Child;
    </pre>

    <img src="graphics/Inheritance/classic_02.png" alt="" style="position: absolute; top: 2em; right: 0; width: 50%">
</div>

<div class="slide">
    <h1>Classic Inheritance</h1>

    <pre class="brush: js, highlight: [9]">
        function Parent() {}
        function Child() {}





        Child.prototype = new Parent();
        Child.prototype.constructor = Child;
    </pre>

    <img src="graphics/Inheritance/classic_03.png" alt="" style="position: absolute; top: 2em; right: 0; width: 50%">
</div>

<div class="slide">
    <h1>Classic Inheritance</h1>

    <div style="font-size: 50%">
        <pre class="brush: js">
            function Parent() {}
            Parent.prototype = {
                getSkinColor: function () {
                    return "red";
                },
                getEyesColor: function () {
                    return "green";
                }
            }
            function Child(name) {
                this.name = name;
            }

            Child.prototype = new Parent();
            Child.prototype.constructor = Child;
            Child.prototype.getEyesColor = function () {
                return "green";
            };
            Child.prototype.getHairStyle = function () {
                return "ugly";
            };

            var monster = new Child()
        </pre>
    </div>
</div>

<div class="slide">
    <h1>Content</h1>

    <ul class="content">
        <li class="done">Конструктор</li>
        <li class="done">Делегирующее наследование</li>
        <li class="done">Делегирующее наследование в JS</li>
        <li class="done">Prototype & Constructor</li>
        <li class="done">Classic Inheritance</li>
        <li class="current">Extend Function</li>
        <li>Other inheritance models</li>
        <li>Inheritance problems</li>
    </ul>
</div>

<div class="slide">
    <h1>Extend</h1>

    <pre class="brush: js">
        function extend(A, B) { // Child, Parent
            var F = function() { }
            F.prototype = B.prototype
            A.prototype = new F()
            A.prototype.constructor = A
        }
    </pre>
</div>

<div class="slide">
    <h1>Extend 01</h1>

    <pre class="brush: js, highlight: 1">
        function extend(A, B) { // Child, Parent
            var F = function() { }
            F.prototype = B.prototype
            A.prototype = new F()
            A.prototype.constructor = A
        }
    </pre>
</div>

<div class="slide">
    <h1>Child, Parent</h1>

    <img src="graphics/Inheritance/extend-01.png" alt="">
</div>

<div class="slide">
    <h1>Extend 02</h1>

    <pre class="brush: js, highlight: 2">
        function extend(A, B) { // Child, Parent
            var F = function() { }
            F.prototype = B.prototype
            A.prototype = new F()
            A.prototype.constructor = A
        }
    </pre>
</div>

<div class="slide">
    <h1>var F = function() { }</h1>

    <img src="graphics/Inheritance/extend-02.png" alt="">
</div>

<div class="slide">
    <h1>Extend 03</h1>

    <pre class="brush: js, highlight: 3">
        function extend(A, B) { // Child, Parent
            var F = function() { }
            F.prototype = B.prototype
            A.prototype = new F()
            A.prototype.constructor = A
        }
    </pre>
</div>

<div class="slide">
    <h1>F.prototype = Parent.prototype</h1>

    <img src="graphics/Inheritance/extend-03.png" alt="">
</div>

<div class="slide">
    <h1>Extend 04</h1>

    <pre class="brush: js, highlight: 4">
        function extend(A, B) { // Child, Parent
            var F = function() { }
            F.prototype = B.prototype
            A.prototype = new F()
            A.prototype.constructor = A
        }
    </pre>
</div>

<div class="slide">
    <h1>Child.prototype = new F()</h1>

    <img src="graphics/Inheritance/extend-04.png" alt="">
</div>

<div class="slide">
    <h1>Extend 05</h1>

    <pre class="brush: js, highlight: 5">
        function extend(A, B) { // Child, Parent
            var F = function() { }
            F.prototype = B.prototype
            A.prototype = new F()
            A.prototype.constructor = A
        }
    </pre>
</div>

<div class="slide">
    <h1>Child.prototype.constructor = Child</h1>

    <img src="graphics/Inheritance/extend-05.png" alt="">
</div>

<div class="slide">
    <h1>Extend Result</h1>

    <pre class="brush: js, highlight: 4">
        function A () {};
        function B () {};

        extend(A, B);
    </pre>

    <img class="incremental" src="graphics/Inheritance/extend-res.png" alt="" style="position: absolute; top: 2em; right: 1em;">

</div>

<div class="slide">
    <h1>Extend Result Object</h1>

    <pre class="brush: js, highlight: 6">
        function A () {};
        function B () {};

        extend(A, B);

        var a = new A();
    </pre>

    <img class="incremental" src="graphics/Inheritance/extend-obj.png" alt="" style="position: absolute; top: 2.5em; right: 0; width: 65%">
</div>

<div class="slide">
    <h1>Extend</h1>

    <p>Как быть с конструктарами?</p>
</div>

<div class="slide">
    <h1>Content</h1>

    <ul class="content">
        <li class="done">Конструктор</li>
        <li class="done">Делегирующее наследование</li>
        <li class="done">Делегирующее наследование в JS</li>
        <li class="done">Prototype & Constructor</li>
        <li class="done">Classic Inheritance</li>
        <li class="done">Extend Function</li>
        <li class="current">Other inheritance models</li>
        <li>Inheritance problems</li>
    </ul>
</div>

<!-- Inheritance -->
<div class="slide">
    <h1>Модели наследования</h1>

    <ul>
        <li>Статическая классовая организация</li>
        <li>Прототипная: Делегирующая модель</li>
        <li>Прототипная: Каскадная модель</li>
        <li>Factory</li>
    </ul>
</div>

<div class="slide">
    <h1>Статическая классовая организация</h1>
</div>

<div class="slide">
    <h1>Делегирующая модель</h1>

    <p>Cреда исполнения способна выполнять диспетчеризацию вызовов методов (или поиск нужных данных) просто следуя по цепочке делегирующих указателей (от объекта к его прототипу), до совпадения</p>
</div>

<div class="slide">
    <h1>Делегирующая 01</h1>

    <pre class="brush: js">
        function extend(Child, Parent) {
            var F = function() { }
            F.prototype = Parent.prototype
            Child.prototype = new F()
            Child.prototype.constructor = Child
        }

        function A () {};
        function B () {};
        extend(A, B);

        var a = new A();
    </pre>

    <img src="graphics/Inheritance/extend-obj.png" alt="" style="position: absolute; bottom: 1em; right: 0; width: 60%">

</div>

<div class="slide">
    <h1>Делегирующая 02</h1>

    <pre class="brush: js">
        function inheritFrom(object) {
            function F() {};
            F.prototype = object;
            return new F;
        }

    </pre>

    <img src="graphics/OOP/clone-res.png" alt="" style="position: absolute; top: 8em; right: 0; ">
</div>

<div class="slide">
    <h1>Делегирующая 02: Example</h1>

    <pre class="brush: js">
        var Person = {
            name: "noname",
            sayHello: function () {
                return "Hello, my name is " + this.name;
            }
        }



        var me = inheritFrom(Person);
        me.name = "Alex";
    </pre>

    <img src="graphics/OOP/clone-res-02.png" alt="" style="position: absolute; top: 8em; right: 0; width: 60%">
</div>

<div class="slide">
    <h1>Каскадная модель</h1>

    <p>Новый обьект пораждается из существующего полным его копированием.</p>

    <div class="incremental">
        <pre class="brush: js">
            function clone(obj) {
                var res = {};
                for(methodName in obj) {
                    res[methodName] = obj[methodName];
                }

                return res;
            }
        </pre>
    </div>
</div>

<div class="slide">
    <h1>Factory</h1>

    <pre class="brush: js">
        function Animal(name) {
            var speed = 10;
            return {
                name: name,
                run: function(distance) {
                    return distance / speed
                }
            }
        }
        pet1 = Animal();
        pet2 = Animal();
    </pre>
</div>

<div class="slide">
    <h1>Factory</h1>

    <img src="graphics/OOP/factory.png" alt="">
</div>

<div class="slide">
    <h1>Factory</h1>

    <pre class="brush: js">
        function Rabbit(name) {
            var me = Animal(name)

            var jumps = 0

            me.jump = function() { jumps++ }
            me.getJumps = function() { return jumps }

            me.constructor = arguments.callee

            return me
        }
    </pre>
</div>

<div class="slide">
    <h1>instanceof</h1>

    <pre class="brush: js">
        if (someObject instanceof SomeConstructor) {
            ...
        }
    </pre>

    <p>instanceof берёт прототип объекта — SomeConstructor.prototype и проверяет его наличие в цепи прототипов, начиная от someObject.[[Prototype]]</p>
</div>

<div class="slide">
    <h1>instanceof</h1>

    <pre class="brush: js">
        function A() {}
        A.prototype.x = 10;

        var a = new A();
        console.log(a.x, a instanceof A); // 10, true

        A.prototype = null;
        console.log(a.x); // 10
        console.log(a instanceof A); // ошибка, A.prototype – не объект
    </pre>
</div>
<!-- Inheritance End -->

<div class="slide">
    <h1>Content</h1>

    <ul class="content">
        <li class="done">Конструктор</li>
        <li class="done">Делегирующее наследование</li>
        <li class="done">Делегирующее наследование в JS</li>
        <li class="done">Prototype & Constructor</li>
        <li class="done">Classic Inheritance</li>
        <li class="done">Extend Function</li>
        <li class="current">Other inheritance models</li>
        <li>Inheritance problems</li>
    </ul>
</div>
<!-- Inheritance Problems -->
<div class="slide">
    <h1>Inheritance Problems</h1>

    <ul>
        <li>Всегда ли нам нужно наследование?</li>
        <li><a href="http://ru.wikipedia.org/wiki/Хрупкий_базовый_класс" rel="nofollow">Хрупкий базовый класс.</a></li>
        <li><a href="http://en.wikipedia.org/wiki/Yo-yo_problem">Yo-Yo problem.</a></li>
        <li><a href="http://ru.wikipedia.org/wiki/Принцип_подстановки_Лисков" rel="nofollow">Принцип подстановки Лисков</a></li>
        <li>Множественное наследование?</li>
    </ul>
</div>

<div class="slide">
    <h1>Хрупкий базовый класс</h1>

    <ul>
        <li>Mалейшие правки базового класса могут привнести ошибку в производные классы</li>
        <li>Любая успешная модификация базового класса требует предварительного изучения всего дерева наследования</li>
        <li class="solution">Замена наследования агрегацией.</li>
    </ul>
</div>

<div class="slide">
    <h1>Yo-Yo problem.</h1>

    <ul>
        <li>Чем глубже наследование, тем сложней отследить поведение.</li>
        <li class="solution"><a href="http://ru.wikipedia.org/wiki/Магическое_число_семь_плюс-минус_два" rel="nofollow">Магическое число семь плюс-минус два</a></li>
        <li class="solution">Замена наследования агрегацией.</li>
    </ul>
</div>

<div class="slide">
    <h1>Принцип подстановки Лисков.</h1>

    <p>Пусть q(x) является свойством, верным относительно объектов x некоторого типа T. Тогда q(y) также должно быть верным для объектов y типа S, где S является подтипом типа T.</p>

    <ul class="incremental">
        <li><a href="http://ru.wikipedia.org/wiki/Контрактное_программирование" rel="nofollow">Контрактное программирование</a></li>
        <li>TDD or <a href="http://ru.wikipedia.org/wiki/Аспектно-ориентированное_программирование" rel="nofollow">AOP</a></li>
    </ul>
</div>

<div class="slide">
    <h1>AOP</h1>


</div>

<div class="slide">
    <h1>AOP</h1>

    <p>Некоторую функциональность с помощью предложенных методов(ООП, процедуры, ...) невозможно выделить в отдельные сущности</p>

    <div style="font-size: 75%">
        <pre class="brush: java">
            public aspect ServletPerformanceMonitor {
                Object around(HttpRequest request)
                    : execution(* HttpServlet.do*(..)) && args(request,..){
                    long startTime = System.nanoTime();
                    Object retValue = proceed(request);
                    long endTime = System.nanoTime();
                    monitorAgent.record(request.getRequestURI(),
                                        endTime - startTime);
                    return retValue;
                }
            }
        </pre>
    </div>
</div>

<div class="slide">
    <h1>AOP in JS</h1>

    <p>Посредством функциональных аргументов, функцию можно легко декорировать и выполнить в некотором аспекте</p>

    <div style="font-size: 60%; margin-left: 1.5em;">
        <pre class="brush: js">
            // advice definition
            function inTransaction(action) {
              return function () {
                long startTime = new Date();
                Object retValue = action.apply(this, arguments);
                long endTime = new Date();
                monitorAgent.record(request.getRequestURI(),
                                    endTime - startTime);
                return retValue;
              };
            }

            // logic definition
            function createOrder() { ... }

            // add advice to createOrder function
            createOrder = inTransaction(createOrder);
        </pre>
    </div>
</div>

<div class="slide">
    <h1>Множественное наследование?</h1>

    <ul>
        <li><a href="http://ru.wikipedia.org/wiki/Проблема_ромба" rel="nofollow">Ромбовидное наследование</a></li>
        <li class="solution">Interfaces</li>
        <li class="solution">Mix-in</li>
    </ul>
</div>

<div class="slide">
    <h1>Mix-in</h1>

    <ul>
        <li>модуль - реализующий какое-либо чётко выделенное поведение</li>
        <li>Используется для уточнения поведения других классов, не предназначен для порождения самостоятельно используемых объектов</li>
    </ul>
</div>

<div class="slide">
    <h1>Mix-in в Ruby</h1>

    <pre class="brush: ruby">
        class Age
            include Comparable

            attr_accessor(:age)

            def <=>(cmp)
                @age <=> cmp.age
            end
        end
    </pre>
</div>

<div class="slide">
    <h1>Mix-in в JS</h1>

    <pre class="brush: js">
        function augment(receivingClass, givingClass) {
            for(methodName in givingClass.prototype) {
                if(!receivingClass.prototype[methodName]) {
                    receivingClass.prototype[methodName] = givingClass.prototype[methodName];
                }
            }
        }
    </pre>
</div>
<!-- Inheritance Problems End-->

<div class="slide">
    <h1>Links</h1>

    <ul>
        <li>http://javascript.ru/tutorial/object/inheritance</li>
        <li>http://dmitrysoshnikov.com/ecmascript/ru-chapter-7-2-oop-ecmascript-implementation</li>
        <li>Professional JavaScript for web Developers</li>
        <li>Pro JavaScript Design Patterns</li>
    </ul>
</div>

<div class="slide">
    <h1>Вопросы / Предложения</h1>

    <ul>
        <li>Alex.Kolonitsky@gmail.com</li>
        <li>akolonitsky@exadel.com</li>
        <li>Skype: Desargues_</li>
        <li>http://code.google.com/p/javascript-learning-courses/issues/list</li>
    </ul>
</div>

</body>
</html>

